/**
 * 下拉刷新Hook
 * Story 5: Task 2 - 下拉刷新功能
 */

import { useState, useCallback } from 'react'
import { useSpring } from '@react-spring/web'
import { useDrag } from '@use-gesture/react'
import { useHapticFeedback } from './useHapticFeedback'
import { useGestureConflictHandler } from './useGestureConflictHandler'

export interface PullToRefreshOptions {
  threshold?: number
  onRefresh: () => Promise<void>
  enabled?: boolean
  maxPullDistance?: number
}

/**
 * 下拉刷新Hook
 * 提供下拉刷新功能，支持触觉反馈和手势冲突处理
 */
export const usePullToRefresh = ({
  threshold = 80,
  onRefresh,
  enabled = true,
  maxPullDistance = 150,
}: PullToRefreshOptions) => {
  const [isRefreshing, setIsRefreshing] = useState(false)
  const { trigger: triggerHaptic } = useHapticFeedback()
  const { startGesture, endGesture, canStartGesture } = useGestureConflictHandler()

  const [{ y }, api] = useSpring(() => ({ y: 0 }))

  const bind = useDrag(
    ({ down, movement: [, my], velocity: [, vy], direction: [, dy], event }) => {
      // 阻止默认滚动行为
      if (down && my > 0) {
        event?.preventDefault()
      }

      // 检查是否可以触发下拉刷新
      if (!enabled || isRefreshing) {
        return
      }

      // 仅在页面顶部且向下拖动时触发
      if (window.scrollY > 5 || dy < 0) {
        api.start({ y: 0 })
        endGesture('pullRefresh')
        return
      }

      if (down && my > 0) {
        // 尝试开始下拉手势
        if (!canStartGesture('pullRefresh')) {
          return
        }

        startGesture('pullRefresh')

        // 拖动中，使用阻尼效果限制最大拖动距离
        const dampingFactor = 0.6
        const dragY = Math.min(my * dampingFactor, maxPullDistance)
        api.start({ y: dragY, immediate: true })

        // 到达阈值时触发轻微震动提示
        if (dragY >= threshold && dragY < threshold + 5) {
          triggerHaptic('light')
        }
      } else {
        // 释放时判断是否触发刷新
        if (my > threshold && vy > 0.05) {
          setIsRefreshing(true)
          api.start({ y: threshold })

          // 触发震动反馈
          triggerHaptic('medium')

          onRefresh().finally(() => {
            setIsRefreshing(false)
            api.start({ y: 0 })
            endGesture('pullRefresh')
          })
        } else {
          api.start({ y: 0 })
          endGesture('pullRefresh')
        }
      }
    },
    {
      axis: 'y',
      from: () => [0, y.get()],
      filterTaps: true,
      preventDefault: true,
      pointer: { touch: true },
    }
  )

  // 手动触发刷新
  const refresh = useCallback(async () => {
    if (isRefreshing) return

    setIsRefreshing(true)
    api.start({ y: threshold })

    try {
      await onRefresh()
    } finally {
      setIsRefreshing(false)
      api.start({ y: 0 })
    }
  }, [isRefreshing, onRefresh, api, threshold])

  return {
    bind,
    pullY: y,
    isRefreshing,
    refresh,
  }
}
